package com.jie.base.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.jie.base.mapper.CityMapper;
import com.jie.base.repository.UserVisitCityRepository;
import com.jie.common.constant.RedisKey;
import com.jie.common.constant.StrConst;
import com.jie.common.util.BaseParameterHolder;
import com.jie.model.po.base.City;
import com.jie.model.redis.base.CityRedis;
import com.jie.model.vo.base.CityVO;
import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * @author jie
 * @version 1.0 2025-02-15
 */
@Service
@RequiredArgsConstructor
public class CityService {

    private final StringRedisTemplate stringRedisTemplate;

    private final CityMapper cityMapper;

    private final UserVisitCityRepository userVisitCityRepository;

    public List<CityVO> getAllCity() {
        List<CityVO> cities = getAllCityFromRedis();
        if (CollUtil.isNotEmpty(cities)) {
            return cities;
        }
        return getAllCityFromDataBase();
    }

    public List<CityVO> getAllCityFromRedis() {
        String key = RedisKey.getRedisKey(RedisKey.CITY);
        Map<Object, Object> entries = stringRedisTemplate.opsForHash().entries(key);
        if (CollUtil.isNotEmpty(entries)) {
            List<CityVO> cityVOS = new ArrayList<>();
            for (Object value : entries.values()) {
                CityRedis cityRedis = JSONUtil.toBean((String) value, CityRedis.class);
                cityVOS.add(BeanUtil.copyProperties(cityRedis, CityVO.class));
            }
            return cityVOS;
        }
        return CollUtil.empty(CityVO.class);
    }

    public List<CityVO> getAllCityFromDataBase() {
        LambdaQueryWrapper<City> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.orderByAsc(City::getSortOrder);
        List<City> cities = cityMapper.selectList(queryWrapper);
        if (CollUtil.isNotEmpty(cities)) {
            return BeanUtil.copyToList(cities, CityVO.class);
        }
        return CollUtil.empty(CityVO.class);
    }

    /**
     * 获取热门城市信息
     * @return
     */
    public List<CityVO> getHotCity() {
        // redis的sortedset数据结构
        String key = RedisKey.getRedisKey(RedisKey.HOT_CITY);
        Set<ZSetOperations.TypedTuple<String>> hotCities = stringRedisTemplate.opsForZSet().reverseRangeWithScores(key, 0, 5);
        List<CityVO> result = new ArrayList<>();
        if (CollUtil.isNotEmpty(hotCities)) {
            List<ZSetOperations.TypedTuple<String>> toSort = new ArrayList<>(hotCities);
            toSort.sort((o1, o2) -> (int) (o1.getScore() - o2.getScore()));
            for (ZSetOperations.TypedTuple<String> hotCity : toSort) {
                CityVO bean = JSONUtil.toBean(hotCity.getValue(), CityVO.class);
                result.add(bean);
            }
        }
        return result;
    }

    /**
     * 最近访问的城市
     * @return
     */
    public List<CityVO> getRecentCity() {
        String userId = BaseParameterHolder.getParameter(StrConst.USER_ID);
        if (StrUtil.isBlank(userId)) {
            return Collections.emptyList();
        }

        return userVisitCityRepository.getRecentCity(Long.valueOf(userId), 6);
    }

}
